package de.re.easymodbus.modbusserver.gui;
import java.lang.Exception.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Random;

import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.GroupLayout;
import javax.swing.JCheckBox;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.awt.Dimension;
import javax.swing.JLabel;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.awt.Font;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;


/**
 *
 * @author Stefan Roßmann
 */
public class NewJFrame extends javax.swing.JFrame implements de.re.easymodbus.modbusserver.ICoilsChangedDelegator, de.re.easymodbus.modbusserver.IHoldingRegistersChangedDelegator, de.re.easymodbus.modbusserver.INumberOfConnectedClientsChangedDelegator, de.re.easymodbus.modbusserver.ILogDataChangedDelegator
{
    
    public de.re.easymodbus.modbusserver.ModbusServer modbusServer = new de.re.easymodbus.modbusserver.ModbusServer();
    /**
     * Creates new form NewJFrame
     */
    public NewJFrame() 
    {
        
        super("EasyModbusTCP Server Simulator");
        initComponents();
        modbusServer.setNotifyCoilsChanged(this);
        modbusServer.setNotifyHoldingRegistersChanged(this);
        modbusServer.setNotifyNumberOfConnectedClientsChanged(this);
        modbusServer.setNotifyLogDataChanged(this);
        modbusServer.setClientConnectionTimeout(0);
        try
        {
            modbusServer.Listen();
        }
        catch (Exception e){}
        jList1.setModel(model);
        
       
        
    }
    
    private void initTables()
    {
        javax.swing.table.DefaultTableModel model1 = (javax.swing.table.DefaultTableModel) jTable1.getModel();
        javax.swing.table.DefaultTableModel model2 = (javax.swing.table.DefaultTableModel) jTable2.getModel();
        javax.swing.table.DefaultTableModel model3 = (javax.swing.table.DefaultTableModel) jTable3.getModel();
        javax.swing.table.DefaultTableModel model4 = (javax.swing.table.DefaultTableModel) jTable4.getModel();
        for (int i = 0; i < 25; i++)
        {
            model1.addRow(new Object[]{String.valueOf(i+1), String.valueOf(false)});
        }
        for (int i = 0; i < 25; i++)
        {
            model2.addRow(new Object[]{String.valueOf(i+1), String.valueOf(false)});
        }
        for (int i = 0; i < 25; i++)
        {
            model3.addRow(new Object[]{String.valueOf(i+1), String.valueOf(0)});
        }
        for (int i = 0; i < 25; i++)
        {
            model4.addRow(new Object[]{String.valueOf(i+1), String.valueOf(0)});
        }
    }
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jScrollBar1 = new javax.swing.JScrollBar();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTable2 = new javax.swing.JTable();
        jScrollBar2 = new javax.swing.JScrollBar();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        jTable3 = new javax.swing.JTable();
        jScrollBar3 = new javax.swing.JScrollBar();
        jPanel4 = new javax.swing.JPanel();
        jScrollPane4 = new javax.swing.JScrollPane();
        jTable4 = new javax.swing.JTable();
        jScrollBar4 = new javax.swing.JScrollBar();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jPanel5 = new javax.swing.JPanel();
        jPanel5.setAlignmentX(Component.LEFT_ALIGNMENT);
        jPanel5.setAlignmentY(Component.TOP_ALIGNMENT);
        jLabel4 = new javax.swing.JLabel();
        jCheckBox1 = new javax.swing.JCheckBox();
        jCheckBox2 = new javax.swing.JCheckBox();
        jCheckBox3 = new javax.swing.JCheckBox();
        jCheckBox4 = new javax.swing.JCheckBox();
        jCheckBox5 = new javax.swing.JCheckBox();
        jCheckBox6 = new javax.swing.JCheckBox();
        jCheckBox7 = new javax.swing.JCheckBox();
        jCheckBox8 = new javax.swing.JCheckBox();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jCheckBox9 = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);
        setSize(new Dimension(888, 640));
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        jTabbedPane1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTabbedPane1MouseClicked(evt);
            }
        });

        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Address", "Value"
            }
        ));
        jTable1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTable1MouseClicked(evt);
            }
        });
        jTable1.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jTable1PropertyChange(evt);
            }
        });
        jScrollPane1.setViewportView(jTable1);

        jScrollBar1.setBlockIncrement(1);
        jScrollBar1.setMaximum(65534);
        jScrollBar1.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                jScrollBar1AdjustmentValueChanged(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
            .addComponent(jScrollBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Discrete Inputs", jPanel1);

        jTable2.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Address", "Value"
            }
        ));
        jTable2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTable2MouseClicked(evt);
            }
        });
        jTable2.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jTable2PropertyChange(evt);
            }
        });
        jScrollPane2.setViewportView(jTable2);

        jScrollBar2.setBlockIncrement(1);
        jScrollBar2.setMaximum(65534);
        jScrollBar2.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                jScrollBar2AdjustmentValueChanged(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 228, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollBar2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
            .addComponent(jScrollBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Coils", jPanel2);

        jTable3.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Address", "Value"
            }
        ));
        jTable3.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jTable3PropertyChange(evt);
            }
        });
        jScrollPane3.setViewportView(jTable3);

        jScrollBar3.setBlockIncrement(1);
        jScrollBar3.setMaximum(65534);
        jScrollBar3.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                jScrollBar3AdjustmentValueChanged(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 227, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollBar3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
            .addComponent(jScrollBar3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Input Registers", jPanel3);

        jPanel4.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jPanel4PropertyChange(evt);
            }
        });

        jTable4.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Address", "Value"
            }
        ));
        jTable4.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jTable4PropertyChange(evt);
            }
        });
        jScrollPane4.setViewportView(jTable4);

        jScrollBar4.setBlockIncrement(1);
        jScrollBar4.setMaximum(65534);
        jScrollBar4.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                jScrollBar4AdjustmentValueChanged(evt);
            }
        });

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollBar4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
            .addComponent(jScrollBar4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Holding Registers", jPanel4);

        jLabel1.setFont(new java.awt.Font("Microsoft Sans Serif", 1, 18)); // NOI18N
        jLabel1.setForeground(new java.awt.Color(102, 204, 0));
        jLabel1.setText("...Modbus-TCP Server Listening (Port 502)...");



        jLabel3.setText("Version 2.5");
        jLabel3.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

        jPanel5.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jLabel4.setText("Supported Function codes:");

        jCheckBox1.setSelected(true);
        jCheckBox1.setText("FC 01 (Read Coils)");
        jCheckBox1.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox1StateChanged(evt);
            }
        });

        jCheckBox2.setSelected(true);
        jCheckBox2.setText("FC 02 (Read Discrete Inputs)");
        jCheckBox2.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox2StateChanged(evt);
            }
        });

        jCheckBox3.setSelected(true);
        jCheckBox3.setText("FC 03 (Read Holding Registers)");
        jCheckBox3.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox3StateChanged(evt);
            }
        });

        jCheckBox4.setSelected(true);
        jCheckBox4.setText("FC 04 (Read Input Registers)");
        jCheckBox4.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox4StateChanged(evt);
            }
        });

        jCheckBox5.setSelected(true);
        jCheckBox5.setText("FC 05 (Write Single Coil)");
        jCheckBox5.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox5StateChanged(evt);
            }
        });

        jCheckBox6.setSelected(true);
        jCheckBox6.setText("FC 06 (Write Single Register)");
        jCheckBox6.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox6StateChanged(evt);
            }
        });

        jCheckBox7.setSelected(true);
        jCheckBox7.setText("FC 15 (Write Multiple Coils)");
        jCheckBox7.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox7StateChanged(evt);
            }
        });

        jCheckBox8.setSelected(true);
        jCheckBox8.setText("FC 16 (Write Multiple Registers)");
        jCheckBox8.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox8StateChanged(evt);
            }
        });

        javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
        jPanel5Layout.setHorizontalGroup(
        	jPanel5Layout.createParallelGroup(Alignment.LEADING)
        		.addGroup(Alignment.TRAILING, jPanel5Layout.createSequentialGroup()
        			.addContainerGap(29, Short.MAX_VALUE)
        			.addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING)
        				.addGroup(jPanel5Layout.createSequentialGroup()
        					.addGap(21)
        					.addComponent(jLabel4))
        				.addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING)
        					.addComponent(jCheckBox2)
        					.addComponent(jCheckBox1)
        					.addComponent(jCheckBox3)
        					.addComponent(jCheckBox4)
        					.addComponent(jCheckBox5)
        					.addComponent(jCheckBox6)
        					.addComponent(jCheckBox7)
        					.addComponent(jCheckBox8)))
        			.addGap(22))
        );
        jPanel5Layout.setVerticalGroup(
        	jPanel5Layout.createParallelGroup(Alignment.LEADING)
        		.addGroup(jPanel5Layout.createSequentialGroup()
        			.addComponent(jLabel4)
        			.addPreferredGap(ComponentPlacement.RELATED)
        			.addComponent(jCheckBox1)
        			.addPreferredGap(ComponentPlacement.RELATED)
        			.addComponent(jCheckBox2)
        			.addPreferredGap(ComponentPlacement.RELATED)
        			.addComponent(jCheckBox3)
        			.addPreferredGap(ComponentPlacement.RELATED)
        			.addComponent(jCheckBox4)
        			.addPreferredGap(ComponentPlacement.RELATED)
        			.addComponent(jCheckBox5)
        			.addPreferredGap(ComponentPlacement.RELATED)
        			.addComponent(jCheckBox6)
        			.addPreferredGap(ComponentPlacement.RELATED)
        			.addComponent(jCheckBox7)
        			.addPreferredGap(ComponentPlacement.RELATED)
        			.addComponent(jCheckBox8)
        			.addContainerGap(11, Short.MAX_VALUE))
        );
        jPanel5.setLayout(jPanel5Layout);

        jLabel5.setText("<html><font color=blue><u>http://www.EasyModbusTCP.net</u></font></html>");
        jLabel5.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jLabel5MousePressed(evt);
            }
        });

        jLabel6.setText("Number of connected clients: ");

        jLabel7.setText("0");

        jCheckBox9.setSelected(true);
        jCheckBox9.setText("Show Protocol Informations");
        jList1 = new javax.swing.JList();
        jList1.setAutoscrolls(false);
        jList1.setAlignmentY(Component.BOTTOM_ALIGNMENT);
        jList1.setAlignmentX(Component.LEFT_ALIGNMENT);
        jList1.setFont(new Font("Tahoma", Font.PLAIN, 9));
        
        chckbxEnableWebview = new JCheckBox("Enable Web View");
        chckbxEnableWebview.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent e) {
				WebViewStateChanged(e);
				
			}
        });
        
        lblWebViewAddress = new JLabel("Webview-address:");
        lblWebViewAddress.setVisible(false);
        
        lblLink = new JLabel("link");
        lblLink.addMouseListener(new MouseAdapter() {
        	@Override
        	public void mouseClicked(MouseEvent arg0) {
        		linkClicked();
        	}
        });
        lblLink.setVisible(false);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        layout.setHorizontalGroup(
        	layout.createParallelGroup(Alignment.LEADING)
        		.addGroup(layout.createSequentialGroup()
        			.addGroup(layout.createParallelGroup(Alignment.LEADING)
        				.addGroup(layout.createSequentialGroup()
        					.addContainerGap()
        					.addComponent(jLabel2)
        					.addGap(6)
        					.addGroup(layout.createParallelGroup(Alignment.TRAILING, false)
        						.addGroup(layout.createSequentialGroup()
        							.addComponent(jLabel5)
        							.addGap(624))
        						.addGroup(layout.createSequentialGroup()
        							.addGroup(layout.createParallelGroup(Alignment.LEADING)
        								.addGroup(layout.createSequentialGroup()
        									.addComponent(jLabel6)
        									.addPreferredGap(ComponentPlacement.RELATED)
        									.addComponent(jLabel7)
        									.addGap(59)
        									.addComponent(jLabel3))
        								.addGroup(layout.createSequentialGroup()
        									.addComponent(jPanel5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
        									.addGap(6)
        									.addComponent(chckbxEnableWebview))
        								.addGroup(layout.createSequentialGroup()
        									.addGap(430)
        									.addComponent(jCheckBox9))
        								.addComponent(jList1, GroupLayout.PREFERRED_SIZE, 583, GroupLayout.PREFERRED_SIZE)
        								.addGroup(layout.createSequentialGroup()
        									.addComponent(lblWebViewAddress)
        									.addPreferredGap(ComponentPlacement.RELATED)
        									.addComponent(lblLink)))
        							.addPreferredGap(ComponentPlacement.RELATED)
        							.addComponent(jTabbedPane1, GroupLayout.PREFERRED_SIZE, 279, GroupLayout.PREFERRED_SIZE))))
        				.addGroup(layout.createSequentialGroup()
        					.addGap(293)
        					.addComponent(jLabel1)))
        			.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
        	layout.createParallelGroup(Alignment.TRAILING)
        		.addGroup(layout.createSequentialGroup()
        			.addComponent(jLabel1)
        			.addPreferredGap(ComponentPlacement.RELATED, 6, Short.MAX_VALUE)
        			.addGroup(layout.createParallelGroup(Alignment.TRAILING)
        				.addGroup(layout.createSequentialGroup()
        					.addComponent(jCheckBox9)
        					.addPreferredGap(ComponentPlacement.UNRELATED))
        				.addGroup(layout.createParallelGroup(Alignment.LEADING)
        					.addGroup(layout.createSequentialGroup()
        						.addGap(16)
        						.addComponent(jLabel2))
        					.addGroup(layout.createSequentialGroup()
        						.addPreferredGap(ComponentPlacement.RELATED)
        						.addComponent(jLabel5)
        						.addPreferredGap(ComponentPlacement.RELATED)
        						.addGroup(layout.createParallelGroup(Alignment.BASELINE)
        							.addComponent(jLabel6)
        							.addComponent(jLabel7)
        							.addComponent(jLabel3)))))
        			.addGap(8)
        			.addGroup(layout.createParallelGroup(Alignment.TRAILING)
        				.addGroup(layout.createSequentialGroup()
        					.addComponent(jList1, GroupLayout.PREFERRED_SIZE, 259, GroupLayout.PREFERRED_SIZE)
        					.addPreferredGap(ComponentPlacement.RELATED)
        					.addGroup(layout.createParallelGroup(Alignment.LEADING)
        						.addComponent(chckbxEnableWebview)
        						.addComponent(jPanel5, GroupLayout.PREFERRED_SIZE, 207, GroupLayout.PREFERRED_SIZE))
        					.addPreferredGap(ComponentPlacement.RELATED)
        					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
        						.addComponent(lblWebViewAddress)
        						.addComponent(lblLink))
        					.addGap(19))
        				.addGroup(layout.createSequentialGroup()
        					.addComponent(jTabbedPane1, GroupLayout.PREFERRED_SIZE, 502, GroupLayout.PREFERRED_SIZE)
        					.addPreferredGap(ComponentPlacement.RELATED)))
        			.addGap(2))
        );
        getContentPane().setLayout(layout);

        jLabel5.getAccessibleContext().setAccessibleName("<html><font color=blue><u>http://www.EasyModbusTCP.net</u></font></html>");
        jLabel5.getAccessibleContext().setAccessibleDescription("");

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jLabel5MousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel5MousePressed
        try
        {
        java.awt.Desktop.getDesktop().browse(new java.net.URI("http://www.EasyModbusTCP.net"));
        }
        catch (Exception ex){}
    }//GEN-LAST:event_jLabel5MousePressed

    private void jCheckBox1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBox1StateChanged
        if (modbusServer.getFunctionCode1Disabled())
            modbusServer.setFunctionCode1Disabled(false);
        else
            modbusServer.setFunctionCode1Disabled(true); 
    }//GEN-LAST:event_jCheckBox1StateChanged

    private void jCheckBox2StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBox2StateChanged
        if (modbusServer.getFunctionCode2Disabled())
            modbusServer.setFunctionCode2Disabled(false);
        else
            modbusServer.setFunctionCode2Disabled(true); 
    }//GEN-LAST:event_jCheckBox2StateChanged

    private void jCheckBox3StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBox3StateChanged
        if (modbusServer.getFunctionCode3Disabled())
            modbusServer.setFunctionCode3Disabled(false);
        else
            modbusServer.setFunctionCode3Disabled(true); 
    }//GEN-LAST:event_jCheckBox3StateChanged

    private void jCheckBox4StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBox4StateChanged
        if (modbusServer.getFunctionCode4Disabled())
            modbusServer.setFunctionCode4Disabled(false);
        else
            modbusServer.setFunctionCode4Disabled(true);   
    }//GEN-LAST:event_jCheckBox4StateChanged

    private void jCheckBox5StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBox5StateChanged
        if (modbusServer.getFunctionCode5Disabled())
            modbusServer.setFunctionCode5Disabled(false);
        else
            modbusServer.setFunctionCode5Disabled(true); 
    }//GEN-LAST:event_jCheckBox5StateChanged

    private void jCheckBox6StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBox6StateChanged
        if (modbusServer.getFunctionCode6Disabled())
            modbusServer.setFunctionCode6Disabled(false);
        else
            modbusServer.setFunctionCode6Disabled(true); 
    }//GEN-LAST:event_jCheckBox6StateChanged

    private void jCheckBox7StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBox7StateChanged
        if (modbusServer.getFunctionCode15Disabled())
            modbusServer.setFunctionCode15Disabled(false);
        else
            modbusServer.setFunctionCode15Disabled(true); 
    }//GEN-LAST:event_jCheckBox7StateChanged

    private void jCheckBox8StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBox8StateChanged
        if (modbusServer.getFunctionCode16Disabled())
            modbusServer.setFunctionCode16Disabled(false);       
        else
            modbusServer.setFunctionCode16Disabled(true); 
    }//GEN-LAST:event_jCheckBox8StateChanged

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        this.modbusServer.StopListening();
    }//GEN-LAST:event_formWindowClosing

    private void jScrollBar2AdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jScrollBar2AdjustmentValueChanged
        javax.swing.table.DefaultTableModel model2 = (javax.swing.table.DefaultTableModel) jTable2.getModel();
        model2.setNumRows(0);
        for (int i = 0; i < 25; i++)
        {
            if ((i+this.jScrollBar2.getValue()+1) < 65535)
            model2.addRow(new Object[]{String.valueOf(i+this.jScrollBar2.getValue()+1), String.valueOf(modbusServer.coils[i+this.jScrollBar2.getValue()+1])});
        }   
    }//GEN-LAST:event_jScrollBar2AdjustmentValueChanged

    private void jScrollBar3AdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jScrollBar3AdjustmentValueChanged
        javax.swing.table.DefaultTableModel model3 = (javax.swing.table.DefaultTableModel) jTable3.getModel();
        model3.setNumRows(0);
        for (int i = 0; i < 25; i++)
        {
            if ((i+this.jScrollBar3.getValue()+1) < 65535)
            model3.addRow(new Object[]{String.valueOf(i+this.jScrollBar3.getValue()+1), String.valueOf(modbusServer.inputRegisters[i+this.jScrollBar3.getValue()+1])});
        }   
    }//GEN-LAST:event_jScrollBar3AdjustmentValueChanged

    private void jScrollBar4AdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jScrollBar4AdjustmentValueChanged
        this.holdingRegistersChangedEvent();
    }//GEN-LAST:event_jScrollBar4AdjustmentValueChanged

    private void jScrollBar1AdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jScrollBar1AdjustmentValueChanged
        javax.swing.table.DefaultTableModel model1 = (javax.swing.table.DefaultTableModel) jTable1.getModel();
        model1.setNumRows(0);
        for (int i = 0; i < 25; i++)
        {
            if ((i+this.jScrollBar1.getValue()+1) < 65535)
            model1.addRow(new Object[]{String.valueOf(i+this.jScrollBar1.getValue()+1), String.valueOf(modbusServer.discreteInputs[i+this.jScrollBar1.getValue()+1])});
           
        }   
    }//GEN-LAST:event_jScrollBar1AdjustmentValueChanged

    private void jTable1PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTable1PropertyChange
        for (int i = 0; i < jTable1.getRowCount(); i++)
        {
            this.modbusServer.setDiscreteInput(Boolean.valueOf((String)this.jTable1.getValueAt(i, 1)), i+this.jScrollBar1.getValue()+1);
        }
        jScrollBar1AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable1PropertyChange

    private void jTable2PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTable2PropertyChange
        for (int i = 0; i < jTable2.getRowCount(); i++)
        {
            this.modbusServer.setCoil(Boolean.valueOf((String)this.jTable2.getValueAt(i, 1)), i+this.jScrollBar2.getValue()+1);
            
        }
        jScrollBar2AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable2PropertyChange

    private void jTable3PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTable3PropertyChange
        for (int i = 0; i < jTable3.getRowCount(); i++)
        {
            this.modbusServer.setInputRegister(Integer.valueOf((String)this.jTable3.getValueAt(i, 1)), i+this.jScrollBar3.getValue()+1);

        }
        jScrollBar3AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable3PropertyChange

    private void jPanel4PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jPanel4PropertyChange

    }//GEN-LAST:event_jPanel4PropertyChange

    private void jTable4PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTable4PropertyChange
                for (int i = 0; i < jTable4.getRowCount(); i++)
        {
            this.modbusServer.setHoldingRegister(Integer.valueOf((String)this.jTable4.getValueAt(i, 1)), i+this.jScrollBar4.getValue()+1);
           
        }
        jScrollBar4AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable4PropertyChange

    private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTable1MouseClicked
        
        this.modbusServer.setDiscreteInput((!this.modbusServer.getDiscreteInput(jTable1.getSelectedRow() + this.jScrollBar1.getValue() + 1)),(jTable1.getSelectedRow() + this.jScrollBar1.getValue() + 1));

        jScrollBar1AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable1MouseClicked

    private void jTabbedPane1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTabbedPane1MouseClicked

    }//GEN-LAST:event_jTabbedPane1MouseClicked

    private void jTable2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTable2MouseClicked
        this.modbusServer.setCoil((!this.modbusServer.getCoil(jTable2.getSelectedRow() + this.jScrollBar2.getValue() + 1)),(jTable2.getSelectedRow() + this.jScrollBar2.getValue() + 1));
        jScrollBar2AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable2MouseClicked

    public void coilsChangedEvent()
    {
        javax.swing.table.DefaultTableModel model2 = (javax.swing.table.DefaultTableModel) jTable2.getModel();
        model2.setNumRows(0);
        for (int i = 0; i < 25; i++)
        {
            if ((i+this.jScrollBar2.getValue()+1) < 65535)
            model2.addRow(new Object[]{String.valueOf(i+this.jScrollBar2.getValue()+1), String.valueOf(modbusServer.coils[i+this.jScrollBar2.getValue()+1])});
        }   
    }
    
    public void holdingRegistersChangedEvent()
    {
        javax.swing.table.DefaultTableModel model4 = (javax.swing.table.DefaultTableModel) jTable4.getModel();
        model4.setNumRows(0);
        for (int i = 0; i < 25; i++)
        {
            if ((i+this.jScrollBar4.getValue()+1) < 65535)
                model4.addRow(new Object[]{String.valueOf(i+this.jScrollBar4.getValue()+1), String.valueOf(modbusServer.holdingRegisters[i+this.jScrollBar4.getValue()+1])});
        }   
    }   
    
    public void NumberOfConnectedClientsChanged()
    {
        this.jLabel7.setText(String.valueOf(modbusServer.getNumberOfConnectedClients()));
    }
    
    javax.swing.DefaultListModel model = new javax.swing.DefaultListModel();
    public void logDataChangedEvent()
    {
        if (jCheckBox9.getSelectedObjects() == null)
            return;
        
        
        //model.removeAllElements();
        
        String listBoxData;
        for (int i = 0; i < 2; i++)
                    {
    
                        if (modbusServer.getLogData()[i] == null)
                            break;
                        if (modbusServer.getLogData()[i].request)
                        {
                            listBoxData = modbusServer.getLogData()[i].timeStamp.getTime() +" Request from Client - Functioncode: " + String.valueOf(modbusServer.getLogData()[i].functionCode);
                            if (modbusServer.getLogData()[i].functionCode <= 4)
                            {
                                listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Quantity: " + String.valueOf(modbusServer.getLogData()[i].quantity);
                            }
                            if (modbusServer.getLogData()[i].functionCode == 5)
                            {
                                listBoxData = listBoxData + " Output Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Output Value: ";
                                if (modbusServer.getLogData()[i].receiveCoilValues[0] == 0)
                                    listBoxData = listBoxData + "False";
                                if (modbusServer.getLogData()[i].receiveCoilValues[0] == 0xFF00)
                                    listBoxData = listBoxData + "True";
                            }
                            if (modbusServer.getLogData()[i].functionCode == 6)
                            {
                                listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Register Value: " + String.valueOf(modbusServer.getLogData()[i].receiveRegisterValues[0]);
                            }
                            if (modbusServer.getLogData()[i].functionCode == 15)
                            {
                                listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Quantity: " + String.valueOf(modbusServer.getLogData()[i].quantity) + " Byte Count: " + String.valueOf(modbusServer.getLogData()[i].byteCount) + " Values Received: ";
                                for (int j = 0; j < modbusServer.getLogData()[i].quantity; j++)
                                {
                                    int shift = j % 16;
                                    if ((i == modbusServer.getLogData()[i].quantity - 1) & (modbusServer.getLogData()[i].quantity % 2 != 0))
                                    {
                                        if (shift < 8)
                                            shift = shift + 8;
                                        else
                                            shift = shift - 8;
                                    }
                                    int mask = 0x1;
                                    mask = mask << (shift);
                                    if ((modbusServer.getLogData()[i].receiveCoilValues[j / 16] & mask) == 0)
                                        listBoxData = listBoxData + " False";
                                    else
                                        listBoxData = listBoxData + " True";
                                }
                            }
                            if (modbusServer.getLogData()[i].functionCode == 16)
                            {
                                listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Quantity: " + String.valueOf(modbusServer.getLogData()[i].quantity) + " Byte Count: " + String.valueOf(modbusServer.getLogData()[i].byteCount) + " Values Received: ";
                                for (int j = 0; j < modbusServer.getLogData()[i].quantity; j++)
                                {
                                    listBoxData = listBoxData + " " + modbusServer.getLogData()[i].receiveRegisterValues[j];
                                }
                            }
                            model.add(0,listBoxData);
                            
                    
                        }
                        if (modbusServer.getLogData()[i].response)
                        {
                            if (modbusServer.getLogData()[i].exceptionCode > 0)
                            {
                                listBoxData = ("Response To Client - Error code: " + String.valueOf(modbusServer.getLogData()[i].errorCode));
                                listBoxData = listBoxData + " Exception Code: " + String.valueOf(modbusServer.getLogData()[i].exceptionCode);
                                model.add(0,listBoxData);
                               

                            }
                            else
                            {
                                listBoxData = (modbusServer.getLogData()[i].timeStamp.getTime() + " Response To Client - Functioncode: " + String.valueOf(modbusServer.getLogData()[i].functionCode));

                                if (modbusServer.getLogData()[i].functionCode <= 4)
                                {
                                 
                                    listBoxData = listBoxData + " Bytecount: " + String.valueOf((int)modbusServer.getLogData()[i].byteCount) + " Values sent: ";
                                }
                                if (modbusServer.getLogData()[i].functionCode == 5)
                                {
                                    listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Output Value: ";
                                    if (modbusServer.getLogData()[i].receiveCoilValues[0] == 0)
                                        listBoxData = listBoxData + "False";
                                    if (modbusServer.getLogData()[i].receiveCoilValues[0] == 0xFF00)
                                        listBoxData = listBoxData + "True";
                                }
                                if (modbusServer.getLogData()[i].functionCode == 6)
                                {
                                    listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Register Value: " + String.valueOf(modbusServer.getLogData()[i].receiveRegisterValues[0]);
                                }
                                if (modbusServer.getLogData()[i].functionCode == 15)
                                {
                                    listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Quantity: " + String.valueOf(modbusServer.getLogData()[i].quantity);
                                }
                                if (modbusServer.getLogData()[i].functionCode == 16)
                                {
                                    listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Quantity: " + String.valueOf(modbusServer.getLogData()[i].quantity);
                                }
                                if (modbusServer.getLogData()[i].sendCoilValues != null)
                                {
                                    for (int j = 0; j < modbusServer.getLogData()[i].sendCoilValues.length; j++)
                                    {
                                        listBoxData = listBoxData + String.valueOf(modbusServer.getLogData()[i].sendCoilValues[j]) + " ";
                                    }
                                }
                                if (modbusServer.getLogData()[i].sendRegisterValues != null)
                                {
                                    for (int j = 0; j < modbusServer.getLogData()[i].sendRegisterValues.length; j++)
                                    {
                                        listBoxData = listBoxData + String.valueOf(modbusServer.getLogData()[i].sendRegisterValues[j]) + " ";
                                    }
                                }
                                model.add(0,listBoxData);
                            }
                        }
                    }
    }
    
    int topic;
    String link;
    private void WebViewStateChanged(javax.swing.event.ChangeEvent evt)
    {
        topic = new Random().nextInt(99999);
        modbusServer.setMqttRootTopic("easymodbusserver/"+ topic);
        if (chckbxEnableWebview.isSelected())
        {
            modbusServer.setMqttBrokerAddress("www.mqtt-dashboard.com");
            link = "http://www.easymodbustcp.net/webview/easymodbuswebview.html?topic=" + topic;
            lblLink.setText("<html><a href =\""+link+"\">"+link+"</a></html>" );
            lblWebViewAddress.setVisible(true);
            lblLink.setVisible(true);


        }

        else
        {
        	modbusServer.setMqttBrokerAddress(null);
            lblWebViewAddress.setVisible(false);
            lblLink.setVisible(false);

        }
    	
    }
    
    private void linkClicked()
    {
    	 if(Desktop.isDesktopSupported()){
             Desktop desktop = Desktop.getDesktop();
                 try {
					desktop.browse(new URI(link));
				} catch (IOException | URISyntaxException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

         }else{
             Runtime runtime = Runtime.getRuntime();
             try {
                 runtime.exec("xdg-open " + link);
             } catch (IOException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JCheckBox jCheckBox2;
    private javax.swing.JCheckBox jCheckBox3;
    private javax.swing.JCheckBox jCheckBox4;
    private javax.swing.JCheckBox jCheckBox5;
    private javax.swing.JCheckBox jCheckBox6;
    private javax.swing.JCheckBox jCheckBox7;
    private javax.swing.JCheckBox jCheckBox8;
    private javax.swing.JCheckBox jCheckBox9;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JList jList1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JScrollBar jScrollBar1;
    private javax.swing.JScrollBar jScrollBar2;
    private javax.swing.JScrollBar jScrollBar3;
    private javax.swing.JScrollBar jScrollBar4;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTable jTable1;
    private javax.swing.JTable jTable2;
    private javax.swing.JTable jTable3;
    private javax.swing.JTable jTable4;
    private JCheckBox chckbxEnableWebview;
    private JLabel lblWebViewAddress;
    private JLabel lblLink;
}
